﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WorkStation.Frameworks.Core.Extensions;
using WorkStation.Frameworks.EasyBus.DbModel;
using WorkStation.Frameworks.EasyBus.Repositories;

#region MongoDB using

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDB.Driver.Builders;

#endregion

namespace WorkStation.Frameworks.EasyBus.Repositories.Mongo
{
    /// <summary>
    /// EasyBus仓储组件Mongo实现
    /// </summary>
    public class HistoryCenterRepository : IHistoryCenterRepository
    {
        #region 私有变量
        protected MongoDatabase _db = null;
        #endregion

        #region 私有静态变量
        protected static readonly string PublishInfoName = typeof(PublishInfo).Name;
        protected static readonly string SubscribeInfoName = typeof(SubscribeInfo).Name;
        protected static readonly string MessageLogName = typeof(MessageLog).Name;
        protected static readonly string PublishLogName = typeof(MessagePublishLog).Name;
        protected static readonly string ProcessLogName = typeof(MessageProcessLog).Name;
        #endregion

        #region 构造函数

        public HistoryCenterRepository(string mongodbUrl) 
        {
            if (mongodbUrl.IsNullOrEmpty())
            {
                throw new ArgumentNullException("mongodbUrl");
            }

            MongoClient client = new MongoClient(mongodbUrl);
            this._db = client.GetServer().GetDatabase("EasyBusDB");
        }

        #endregion

        #region 公有函数

        /// <summary>
        /// 上传消息日志
        /// </summary>
        /// <param name="log">消息日志</param>
        public void UploadMessageLog(MessageLog log)
        {
            var collection = this._db.GetCollection<MessageLog>(MessageLogName);

            var exists = collection.AsQueryable().FirstOrDefault(v => v.MessageId == log.MessageId);

            if (exists == null)
            {
                collection.Insert(log);
            }
        }

        /// <summary>
        /// 更新消息日志的发布标志位
        /// </summary>
        /// <param name="messageId">消息编号</param>
        /// <param name="value">值</param>
        public void UpdateIsSuccessPublish(string messageId, bool value) 
        {
            var collection = this._db.GetCollection<MessageLog>(MessageLogName);

            collection.Update(Query.EQ("MessageId", BsonValue.Create(messageId)), new UpdateDocument("IsSuccessPublish", BsonValue.Create(value)));
        }

        /// <summary>
        /// 更新消息日志的处理标志位
        /// </summary>
        /// <param name="messageId">消息编号</param>
        /// <param name="value">值</param>
        public void UpdateIsSuccessProcess(string messageId, bool value) 
        {
            var collection = this._db.GetCollection<MessageLog>(MessageLogName);

            collection.Update(Query.EQ("MessageId", BsonValue.Create(messageId)), new UpdateDocument("IsSuccessProcess", BsonValue.Create(value)));
        }

        /// <summary>
        /// 上传消息发布日志
        /// </summary>
        /// <param name="log">发布日志</param>
        public void UploadMessagePublishLog(MessagePublishLog log)
        {
            var collection = this._db.GetCollection<MessagePublishLog>(PublishLogName);

            var publishLog = this.GetMessagePublishLogById(log.MessageId);

            var exists = publishLog.FirstOrDefault(v => v.Mq.Equals(log.Mq));

            if (exists != null)
            {
                log._id = exists._id;
                collection.Update(Query.EQ("_id", BsonValue.Create(exists._id)), new UpdateDocument(log.ToBsonDocument(log.GetType())));
            }
            else
            {
                collection.Insert(log);
            }
        }

        /// <summary>
        /// 上传消息处理日志 
        /// </summary>
        /// <param name="log">处理日志</param>
        public void UploadMessageProcessLog(MessageProcessLog log)
        {
            var collection = this._db.GetCollection<MessageProcessLog>(ProcessLogName);

            var processLog = this.GetMessageProcessLogById(log.MessageId);

            var exists = processLog.FirstOrDefault(v => v.Mq == log.Mq && v.HandleName == log.HandleName);

            if (exists != null)
            {
                log._id = exists._id;
                collection.Update(Query.EQ("_id", BsonValue.Create(exists._id)), new UpdateDocument(log.ToBsonDocument(log.GetType())));
            }
            else
            {
                collection.Insert(log);
            }
        }

        /// <summary>
        /// 获取消息日志
        /// </summary>
        /// <param name="messageId">消息编号</param>
        /// <returns></returns>
        public MessageLog GetMessageLogById(string messageId)
        {
            var log = this._db.GetCollection<MessageLog>(MessageLogName)
                          .AsQueryable()
                          .FirstOrDefault(v => v.MessageId == messageId);

            log.PublishLogs = this.GetMessagePublishLogById(messageId);
            log.ProcessLogs = this.GetMessageProcessLogById(messageId);
            
            return log;
        }

        /// <summary>
        /// 获取消息发布日志
        /// </summary>
        /// <param name="messageId">消息编号</param>
        /// <returns></returns>
        public List<MessagePublishLog> GetMessagePublishLogById(string messageId)
        {
            return this._db.GetCollection<MessagePublishLog>(PublishLogName)
                           .AsQueryable()
                           .Where(v => v.MessageId == messageId)
                           .ToList();
        }

        /// <summary>
        /// 获取消息处理日志
        /// </summary>
        /// <param name="messageId">消息编号</param>
        /// <returns></returns>
        public List<MessageProcessLog> GetMessageProcessLogById(string messageId)
        {
            return this._db.GetCollection<MessageProcessLog>(ProcessLogName)
                           .AsQueryable()
                           .Where(v => v.MessageId == messageId)
                           .ToList();
        }

        /// <summary>
        /// 获取异常的发布日志
        /// </summary>
        /// <returns></returns>
        public List<MessageLog> GetExceptionPublishLog() 
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 获取异常的处理日志
        /// </summary>
        /// <returns></returns>
        public List<MessageLog> GetExceptionProcessLog() 
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IDisposable 成员

        public void Dispose()
        {
            
        }

        #endregion
    }
}
